﻿using System;
using System.Linq;
using msilgc.cbuilder.CSyntaxTree;
using msilgc.cbuilder.MSILSyntaxTree;
using msilgc.CSyntaxTree;
using System.Reflection.Emit;

namespace msilgc.cbuilder.CBuilder
{
    internal class AssignToLocalVariableFactory : ITranslator {

        private static IVariable FindLocalVariable(CMethodBody methodBody, Instruction instruction) {
            if(instruction.Inst == OpCodes.Stloc_0) {
                return methodBody.LocalVariables.ElementAt(0);
            }
            if(instruction.Inst == OpCodes.Stloc_1) {
                return methodBody.LocalVariables.ElementAt(1);
            }
            if(instruction.Inst == OpCodes.Stloc_2) {
                return methodBody.LocalVariables.ElementAt(2);
            }
            if(instruction.Inst == OpCodes.Stloc_3) {
                return methodBody.LocalVariables.ElementAt(3);
            }
            if(instruction.Inst == OpCodes.Stloc_S)
            {
                return methodBody.LocalVariables.ElementAt(instruction.Data.ElementAt(0));
            }
            throw new Exception("unknown instruction: " + instruction);
        }

        public ICStatement TranslateAndAdd(CMethodBody methodBody, CBasicBlock currentBlock, BasicBlock block, Instruction instruction) {
            IVariable localVar = FindLocalVariable(methodBody, instruction);
            IVariable source = EvaluationStackHelper.PopVariableOffEvaluationStack(currentBlock);
            AssignToLocalVariable stm = new AssignToLocalVariable(source, localVar){OnStack = false};
            currentBlock.Statements.Add(stm);
            return stm;
        }
    }
}